package Common;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import Server.ServerUtils;

import Client.ClientUtils;

public class Utils {


	public static final String URL_SEPARATOR = "/";

	public static final char UNIX_SEPARATOR = '/';

	public static final char WINDOWS_SEPARATOR = '\\';


	// Returns the file in byte array.
	public static byte[] getBytesFromFile(File file) throws IOException {


		InputStream FileIs = new FileInputStream(file);

		byte[] bytes = new byte[(int)file.length()];

		// Read in the bytes
		int offset = 0;
		int numRead = 0;
		while (offset < bytes.length
				&& (numRead=FileIs.read(bytes, offset, bytes.length-offset)) >= 0) {
			offset += numRead;
		}

		// Ensure all the bytes have been read in
		if (offset < bytes.length) {
			throw new IOException("Could not completely read file "+ file.getName());
		}


		FileIs.close();
		return bytes;
	}

	public static byte[] getBytesFromFile(String filename) throws IOException {
		File file = new File(filename);
		return getBytesFromFile(file);
	}

	public static byte[] getSHA256hash(byte[] fileInBytes){
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("SHA-256");
			return md.digest(fileInBytes);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}

	public static boolean md256equal(byte[] hashedFileValue, byte[] hashedFileValueFromServer) {
		return MessageDigest.isEqual(hashedFileValue, hashedFileValueFromServer);		
	}

	public static byte[] readInputStream(InputStream stream) throws IOException {
		final int chunkSize = 2048;
		byte[] buf = new byte[chunkSize];
		ByteArrayOutputStream byteStream = new ByteArrayOutputStream(chunkSize);
		int count;
		while ((count=stream.read(buf)) != -1) byteStream.write(buf, 0, count);
		return byteStream.toByteArray();
	}



	public static String ToUnixPath(String path) {
		if (path == null || path.indexOf(WINDOWS_SEPARATOR) == -1){
			return path;
		}
		String newPath = path.replace(WINDOWS_SEPARATOR,UNIX_SEPARATOR);

		if (newPath.length() > 1 && newPath.charAt(1) == ':'){
			return newPath.substring(2);
		} 
		else{
			return newPath;
		}
	}

	/* convert the path string to the local machine's path convention
	 * 
	 */
	public static String toLocalPath(String path){
		if (path == null){
			return path;
		}

		char[] pathChars = new char[path.length()];
		path.getChars(0, path.length(), pathChars, 0);
		for (int i = 0; i < pathChars.length; i++){
			if (pathChars[i] == UNIX_SEPARATOR){
				pathChars[i] = File.separatorChar;
			}
		}

		if(ClientUtils.HOME_DRIVER!=null){
			return new String(ClientUtils.HOME_DRIVER + new String(pathChars));
		}
		else return new String(pathChars);
	}

	public static boolean isFileOK(String fileName, File file) throws IOException {

		if (!file.isFile()) {
			System.out.println("the file: " + fileName + " was not found.");
			return false;
		}
		if (!file.canRead()) {
			throw new IOException(fileName + " is not accessible");

		}
		return true;
	}

	public static boolean isDirOK(String dirName, File dir) throws IOException {

		if (!dir.isDirectory()) {
			System.out.println("Directory " + dirName + " was not found");
			throw new FileNotFoundException(dirName);
		}
		if (!dir.canRead()) {
			throw new IOException(dirName + " is not accessible");
		}
		return true;
	}


	public static byte[] Base64ToByteArray(String B64String){
		byte[] b = null;
		try {
			b = Common.Base64.decode(B64String, Base64.URL_SAFE);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		return b;
	}

	/*return the String representation of the array of bytes in Base64
	 * or null on failure
	 * 
	 */
	public static String byteArrayToBase64(byte[] array){
		String B64 = null;
		try {
			B64 = Base64.encodeBytes(array, Base64.URL_SAFE);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("IO Error.");
			return null;
		}
		return B64;
	}

	//test

	public static void main(String[] args){
		String filename = "/Users/oshri/workspace/alibaba/Client/dir1/D.txt";
		String localFilename = toLocalPath(filename);
		System.out.println(localFilename);
		return;
	}

}